﻿Imports System.IO
Imports System.Security.Cryptography
Imports System.Text

Module modFile
    Public Function Directory_ReturnTemp(Optional ByVal dirName As String = Nothing) As String

        Dim _tmp As String
        Dim _output As String = ""
        Dim _rand As New Random()

        Dim _value As Integer

        If Not (dirName Is Nothing) Then
            _tmp = Path.Combine(Path.GetTempPath, dirName)
            If Directory.Exists(_tmp) = False Then
                Directory.CreateDirectory(_tmp)
                Return _tmp
            End If
        End If

        For i = 0 To 9
            _value = _rand.[Next](1, 36)
            _output += ChrW(IIf(_value <= 26, 64 + _value, (_value - 27) + 48))
        Next

        _tmp = Path.Combine(Path.GetTempPath, _output)

        Directory.CreateDirectory(_tmp)

        Return _tmp
    End Function

    Public Function Directory_Check(ByVal dirPath As String) As Boolean

        Dim dir As String = dirPath
        Dim msg As MsgBoxResult

        If Directory.Exists(dir) = True Then Return True

        msg = MsgBox("Folder does not exist, would you like to create it?", vbYesNoCancel + vbInformation)

        If msg = vbYes Then

            Directory.CreateDirectory(dir)

        ElseIf msg = vbCancel Then

            Return Nothing

        End If

        If Directory.Exists(dir) = True Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function Directory_GetParent(ByVal dir As String, Optional ByVal num As Integer = 0) As String

        Dim dirList As List(Of String)
        Dim _tmp As String

        If dir = Nothing Then Return Nothing

        dir = Path.GetDirectoryName(dir)

        dirList = dir.Split("\").ToList()

        dirList.RemoveAll(AddressOf String_IsEmpty)

        If dirList.Count = 0 Then Return Nothing

        For i = 0 To (num - 1)
            dirList.RemoveAt(dirList.Count - 1)
        Next

        _tmp = String.Join("\", dirList)
        Return _tmp
    End Function

    Public Function File_Exists(ByVal filePath As String) As Boolean

        Return File.Exists(filePath)
    End Function

    Public Function File_GetProductName(ByVal fileName As String) As String

        Dim fileProduct As String

        If File.Exists(fileName) = False Then

            Return Nothing

        End If

        fileProduct = FileVersionInfo.GetVersionInfo(fileName).ProductName

        Return fileProduct
    End Function

    Public Function File_GetFileDescription(ByVal fileName As String) As String

        Dim fileDescription As String

        If File.Exists(fileName) = False Then

            Return Nothing

        End If

        fileDescription = FileVersionInfo.GetVersionInfo(fileName).FileDescription

        Return fileDescription
    End Function

    Public Function File_GetVersionInfo(ByVal fileName As String) As String

        Dim ver As Version
        Dim ret As String

        If File.Exists(fileName) = False Then

            Return Nothing

        End If

        ver = Version.Parse(FileVersionInfo.GetVersionInfo(fileName).FileVersion)

        ret = ver.Major.ToString & "."
        ret = ret & ver.Minor.ToString & "."
        ret = ret & ver.Build.ToString & "."
        ret = ret & ver.Revision.ToString

        Return ret
    End Function

    Public Function File_GetLastModifiedDate(ByVal fileName As String) As String

        Dim tmp As FileInfo

        If File.Exists(fileName) = False Then

            Return Nothing

        End If

        tmp = My.Computer.FileSystem.GetFileInfo(fileName)

        Return tmp.LastWriteTime().ToShortDateString
    End Function

    Public Function File_Locate(ByVal folderBase As String, ByVal fileName As String) As String

        Dim tmp As String()
        Dim i As Integer
        Dim outPath As String = ""

        If (File.Exists(fileName) = False) Or (Directory.Exists(folderBase) = False) Then

            Return Nothing

        End If

        If fileName.Contains("\") Then 'Extract fileName
            fileName = Right(fileName, Len(fileName) - InStrRev(fileName, "\"))
        End If

        tmp = Directory.GetFiles(folderBase, fileName, SearchOption.AllDirectories)

        For i = 0 To (tmp.Count - 1)
            outPath = tmp(i)
        Next i

        File_Locate = outPath
    End Function

    Public Function File_MD5(ByVal fileName As String) As String

        Dim fileStream As FileStream
        Dim cryptMD5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider
        Dim byteTemp As Byte
        Dim tmpReturn As StringBuilder = New StringBuilder

        If File.Exists(fileName) = False Then

            Return Nothing

        End If

        fileStream = New FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)

        cryptMD5.ComputeHash(fileStream)

        fileStream.Close()

        Dim fileHash As Byte() = cryptMD5.Hash

        For Each byteTemp In fileHash

            tmpReturn.Append(String.Format("{0:X1}", byteTemp))

        Next

        Return tmpReturn.ToString.ToUpper
    End Function

    Public Function File_VerifyMD5(ByVal fileName As String, ByVal hashMD5 As String) As Boolean

        Dim fileStream As FileStream
        Dim cryptMD5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider
        Dim byteTemp As Byte
        Dim tmpReturn As StringBuilder = New StringBuilder

        If File.Exists(fileName) = False Then

            Return Nothing

        End If

        fileStream = New FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)

        cryptMD5.ComputeHash(fileStream)

        fileStream.Close()

        Dim fileHash As Byte() = cryptMD5.Hash

        For Each byteTemp In fileHash

            tmpReturn.Append(String.Format("{0:X1}", byteTemp))

        Next

        If tmpReturn.ToString.ToUpper = hashMD5.ToString.ToUpper Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function File_FixPath(ByVal filePath As String, Optional ByVal searchIfNotFound As Boolean = True,
                                 Optional ByVal searchDirectory As String = Nothing) As String

        Dim target As String = filePath

        Dim targetDirectory As String = Path.GetDirectoryName(target)
        Dim targetFileName As String = Path.GetFileName(target)

        If Left(target, 1) = "\" Then

            target = searchDirectory & filePath
            targetDirectory = Path.GetDirectoryName(target)
            targetFileName = Path.GetFileName(target)

        End If

        If File.Exists(target) = True Then

            Return target

        End If

        If (searchIfNotFound = True) Then

            If Not (searchDirectory Is Nothing) Then

                If Directory.Exists(searchDirectory) Then

                    targetDirectory = Path.GetDirectoryName(searchDirectory)

                Else

                    targetDirectory = AppDomain.CurrentDomain.BaseDirectory

                End If

            End If

            target = File_Locate(targetDirectory, targetFileName)

        End If

        If File.Exists(target) = False Then

            Return Nothing

        End If

        Return target
    End Function

    Public Function File_GetPluginVersion(ByVal pathDirectory As String)

        Dim pathDir As String = Path.GetDirectoryName(pathDirectory & "\")

        If Directory.Exists(pathDir) = False Then
            Return Nothing
        End If

        Dim pathPlugin As String = Path.Combine(pathDir, "Plugin.cs")

rrrixRestart:
        If File.Exists(pathPlugin) = False Then
            pathPlugin = Path.Combine(pathDir, "SimpleFollow.cs")
            If File.Exists(pathPlugin) = True Then GoTo rrrixRestart
            pathPlugin = Path.Combine(pathDir, "LumberJack.cs")
            If File.Exists(pathPlugin) = True Then GoTo rrrixRestart
            pathPlugin = Path.Combine(pathDir, "Plugin.Kadala.cs")
            If File.Exists(pathPlugin) = True Then GoTo rrrixRestart
            Return Nothing
        End If

        Dim streamLine As String
        Dim streamOutput As New List(Of String)

        Dim tmpLine As String = ""

        Dim iL As Integer

        Using streamReader As StreamReader = New StreamReader(pathPlugin)

            While streamReader.Peek >= 0
                streamLine = streamReader.ReadLine()
                streamOutput.Add(streamLine)
            End While

        End Using

        For iL = 0 To (streamOutput.Count - 1)

            If streamOutput.Item(iL).Contains("new Version(") = True Then

                tmpLine = String_Between(streamOutput.Item(iL), "new Version(", ");")
                Exit For

            ElseIf streamOutput.Item(iL).Contains(".PluginVersion") = True Then

                pathPlugin = Path.Combine(pathDir,
                                          String_Between(streamOutput.Item(iL), "{ return ", ".PluginVersion; }") &
                                          ".cs")
                GoTo rrrixRestart

            End If
        Next

        If String_IsEmpty(tmpLine) = True Then

            Return Nothing

        Else

            Return tmpLine.Replace(", ", ".")

        End If
    End Function

    Public Function File_GetDiffInfo(ByVal patchPath As String, Optional ByVal boolOriginal As Boolean = True) As String

        Dim _tmpReadLine As String
        Dim _tmpContents As New List(Of String)
        Dim _path As String = patchPath
        Dim _Line
        Dim i As Integer

        If File.Exists(_path) = False Then Return Nothing

        Using fileReader As StreamReader = New StreamReader(_path)

            While fileReader.Peek >= 0
                _tmpReadLine = fileReader.ReadLine()
                _tmpContents.Add(_tmpReadLine)
            End While

        End Using

        For i = 0 To (_tmpContents.Count - 1)

            _Line = _tmpContents.Item(i)

            If (Left(_Line, 4) = "*** ") And (boolOriginal = True) Then 'Old
                Return String_Between(_Line, "*** ", vbTab)
            ElseIf (Left(_Line, 4) = "--- ") And (boolOriginal = False) Then 'New
                Return String_Between(_Line, "--- ", vbTab)
            End If

        Next

        Return Nothing
    End Function

    Public Function File_ReadToList(filePath As String, ByRef outList As List(Of String)) As streamreaderResult

        Dim _return As New List(Of String)
        Dim _line As String

        If File.Exists(filePath) = False Then Return streamreaderResult.FileNotFound

        Try

            Using _reader As StreamReader = New StreamReader(filePath)

                _line = _reader.ReadLine()

                While Not (_line Is Nothing)

                    _return.Add(_line)
                    _line = _reader.ReadLine()

                End While

            End Using

            outList.AddRange(_return)

            Return streamreaderResult.OK

        Catch ex As Exception

            Return streamreaderResult.Unknown

        End Try
    End Function
End Module